//
//  ViewController.swift
//  SwiftDemo1
//
//  Created by zq on 2020/10/20.
//  Copyright © 2020 zq. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    
    var completionCallBack:(()->())?

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
//        demo1()
        getData { (result) in
            print(result)
        }
        
        //1.循环引用的解决方案
//        weak var weakSelf = self
//        loadData {
//            print(weakSelf?.view ?? "nil")
////            print(self.view ?? "nil")  //循环引用
//        }
        //循环引用的第二种解决方案
        // swift 推荐的方式
        // [weak self] 表示 {} 中所有的 self 都是 弱引用
//        loadData {[weak self] in
//            print(self?.view ?? "nil")
//        }
        //第三种方法 知道就好 不安全
        // unowned self 表示 {} 中 所有的self都是 assi gn ,不会强制引用,但是如果对象释放,地址不会发生改变,
        //如果对象被释放,继续调用,就会出现野指针,
//        loadData {[unowned self] in
//            print(self.view ?? "nil")
//        }
        
        sessionNetWork()
        
    }
    
    /**
     session 做网络请求
     */
    func sessionNetWork() {
        let url = URL(string: "http://www.baidu.com")
        URLSession.shared.dataTask(with: url!) { (data, _, error) in
            if(error != nil){
                print("错误")
                return
            }
            
            guard let data = data else{
                print("错误 : \(String(describing: error))")
                return
            }
            
            guard let dataStr = String(bytes: data, encoding: .utf8) else {
                return
            }
            print(dataStr)
        }.resume()
    }
    
    //字符串
    func demo1() {
        let str = "测试abvc"
        print(str.count)
        print(str.lengthOfBytes(using: .utf8))
        
        //格式字符串
        let h = 8
        let m = 9
        let s = 10
        print(String(format: "%02d:%02d:%02d", h,m,s))
        
        print(str.startIndex)
        
    }
    
    /**
        模拟异步获取数据
     */
    func getData(completion:@escaping(_ result:[String])->())  {
        DispatchQueue.global().async { //开启异步,尾随闭包
            //耗时操作
            let result = ["头条","新闻","大消息"]
            DispatchQueue.main.async {
                completion(result)
            }
        }
    }
    /// @escaping 逃逸闭包:为了防止函数结束的时候,闭包被销毁需要使用这个@escaping
    /// 函数中的参数如果是闭包,默认是non-escaping,函数结束,闭包就会被销毁,
    /// 如果存在异步,函数结束可能闭包还没有执行完毕,增加其生命周期
    func loadData(completion:@escaping()->())  {
        completionCallBack = completion //循环引用
        DispatchQueue.global().async {
            print("耗时操作")
            Thread.sleep(forTimeInterval: 3)
            DispatchQueue.main.async {
                completion()
            }
        }
    }
    
    deinit {
        //如果这里不走 证明循环引用了
        print("我去了")
    }
    
    
}

